#ifndef CEEPROM_H_
#define CEEPROM_H


/* indexes of EtherCAT PDOs */
#define EC_PDO_CONTROL_WORD_INDEX	0x6040
#define EC_PDO_STATUS_WORD_INDEX	0x6041
#define EC_PDO_TARGET_POSITION_INDEX	0x607a
#define EC_PDO_TARGET_VELOCITY_INDEX	0x60ff
#define EC_PDO_TARGET_TORQUE_INDEX	0x6071
#define EC_PDO_OPERATION_MODE_INDEX	0x6060
#define EC_PDO_MODE_OF_OP_DIS_INDEX	0x6061
#define EC_PDO_ACTUAL_POSITION_INDEX	0x6064
#define EC_PDO_ACTUAL_VELOCITY_INDEX	0x606c
#define EC_PDO_ACTUAL_TORQUE_INDEX	0x6077
#define EC_PDO_MAX_TORQUE_INDEX         0x6072

#define EEPROM_SYNC_FMMU 0x28
#define EEPROM_SYNC_MNGR 0x29
#define EEPROM_PDO_TX 0x32
#define EEPROM_PDO_RX 0x33

#define RX_SYNC_INDEX 2 
#define TX_SYNC_INDEX 3 

#define DEFAULT_SYNC_COUNT 4
#define DEFAULT_PDO_COUNT 2

typedef enum {
	EEPROM_SM_TYPE_UNKNOWN,
	EEPROM_SM_TYPE_FOR_MAILBOX_OUT,
	EEPROM_SM_TYPE_FOR_MAILBOX_IN,
	EEPROM_SM_TYPE_FOR_DATA_OUTPUT,
	EEPROM_SM_TYPE_FOR_DATA_INPUT,
} eeprom_sm_type_t;

/* Structure used to parse cfg header */
typedef struct eeprom_conf_header {
	uint16_t cfg;
	uint16_t len;
} eeprom_conf_header_t;

/* content of address arrange: 0x08 ~ 0x0f */
typedef struct eeprom_hardware {
	/* 32 bytes */
	uint32_t vendor_id;
	uint32_t product_code;
	uint32_t revision_no;
	uint32_t serial_no;
} eeprom_hardware_t;

/* Protocol value: 0x29 */
typedef struct eeprom_sync {
	/* 8 byte */
	uint16_t addr_start;
	uint16_t data_len;
	uint16_t config_reg;
	uint8_t active;
	uint8_t dir_flag;
} eeprom_sync_t;

typedef struct eeprom_pdo_entry {
	/* 8 byte */
	uint16_t index;
	uint8_t subindex;
	uint8_t name_index;
	uint8_t data_type;
	uint8_t bit_length;
	uint16_t flags;
} eeprom_pdo_entry_t;

/* Protocol value: TxPDO - 0x32 ; RxPDO - 0x33*/
typedef struct eeprom_pdo {
	/* 8 byte */
	uint16_t index;
	uint8_t n_entries;
	uint8_t sm_index;
	uint8_t dc_ref;
	uint8_t name_idx;
	uint16_t flags;
	eeprom_pdo_entry_t entries[0];
} eeprom_pdo_t;


/* struct used to aggrregate the original pdo and its pdo entries in sii words
 * read from eeprom. */
typedef struct eeprom_aggr_pdo {
    /* Points to the address of orignal pdo
     * in sii words read from eeprom */
    eeprom_pdo_t *eeprom_pdo;
    /* Pointer the start address of array of orignal pdos
     * in sii words read from eeprom. */
    eeprom_pdo_entry_t *eeprom_entries;
    /* count of all pdo entries belong to this pdo. */
    uint32_t entry_count;
} eeprom_aggr_pdo_t;

/* a struct used to aggrregate the origal sync manager in sii words
 * read from eeprom and the pdos belonging to it. */
typedef struct eeprom_aggr_sync {
    /* Points to the address of orignal sync manager
     * in sii words read from eeprom */
    eeprom_sync_t *eeprom_sync;
    /* Pointer the start address of array of eeprom_aggr_pdo_t instances,
     * each instance represents a orignal pdo in sii words read from eeprom. */
    eeprom_aggr_pdo_t *aggr_pdo;
    /* count of all pdos belong to this sync manager */
    uint32_t pdo_count;
} eeprom_aggr_sync_t;


#endif